package entities;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.lang.reflect.Method;
import java.util.Map;
import java.io.ObjectOutputStream;
import java.io.FileOutputStream;
import java.io.Serializable;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.FileInputStream;
import java.io.File;

public class EntityManager {

	private static Map<String, List> AllInstance = new HashMap<String, List>();
	
	private static List<User> UserInstances = new LinkedList<User>();
	private static List<ThirdPartyAccount> ThirdPartyAccountInstances = new LinkedList<ThirdPartyAccount>();
	private static List<Deposit> DepositInstances = new LinkedList<Deposit>();
	private static List<Bike> BikeInstances = new LinkedList<Bike>();
	private static List<Order> OrderInstances = new LinkedList<Order>();
	private static List<FaultReport> FaultReportInstances = new LinkedList<FaultReport>();
	private static List<PaymentMethod> PaymentMethodInstances = new LinkedList<PaymentMethod>();
	private static List<Coupon> CouponInstances = new LinkedList<Coupon>();
	private static List<GeoPoint> GeoPointInstances = new LinkedList<GeoPoint>();
	private static List<WeChatPayment> WeChatPaymentInstances = new LinkedList<WeChatPayment>();
	private static List<AlipayUserId> AlipayUserIdInstances = new LinkedList<AlipayUserId>();

	
	/* Put instances list into Map */
	static {
		AllInstance.put("User", UserInstances);
		AllInstance.put("ThirdPartyAccount", ThirdPartyAccountInstances);
		AllInstance.put("Deposit", DepositInstances);
		AllInstance.put("Bike", BikeInstances);
		AllInstance.put("Order", OrderInstances);
		AllInstance.put("FaultReport", FaultReportInstances);
		AllInstance.put("PaymentMethod", PaymentMethodInstances);
		AllInstance.put("Coupon", CouponInstances);
		AllInstance.put("GeoPoint", GeoPointInstances);
		AllInstance.put("WeChatPayment", WeChatPaymentInstances);
		AllInstance.put("AlipayUserId", AlipayUserIdInstances);
	} 
		
	/* Save State */
	public static void save(File file) {
		
		try {
			
			ObjectOutputStream stateSave = new ObjectOutputStream(new FileOutputStream(file));
			
			stateSave.writeObject(UserInstances);
			stateSave.writeObject(ThirdPartyAccountInstances);
			stateSave.writeObject(DepositInstances);
			stateSave.writeObject(BikeInstances);
			stateSave.writeObject(OrderInstances);
			stateSave.writeObject(FaultReportInstances);
			stateSave.writeObject(PaymentMethodInstances);
			stateSave.writeObject(CouponInstances);
			stateSave.writeObject(GeoPointInstances);
			stateSave.writeObject(WeChatPaymentInstances);
			stateSave.writeObject(AlipayUserIdInstances);
			
			stateSave.close();
					
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	/* Load State */
	public static void load(File file) {
		
		try {
			
			ObjectInputStream stateLoad = new ObjectInputStream(new FileInputStream(file));
			
			try {
				
				UserInstances =  (List<User>) stateLoad.readObject();
				AllInstance.put("User", UserInstances);
				ThirdPartyAccountInstances =  (List<ThirdPartyAccount>) stateLoad.readObject();
				AllInstance.put("ThirdPartyAccount", ThirdPartyAccountInstances);
				DepositInstances =  (List<Deposit>) stateLoad.readObject();
				AllInstance.put("Deposit", DepositInstances);
				BikeInstances =  (List<Bike>) stateLoad.readObject();
				AllInstance.put("Bike", BikeInstances);
				OrderInstances =  (List<Order>) stateLoad.readObject();
				AllInstance.put("Order", OrderInstances);
				FaultReportInstances =  (List<FaultReport>) stateLoad.readObject();
				AllInstance.put("FaultReport", FaultReportInstances);
				PaymentMethodInstances =  (List<PaymentMethod>) stateLoad.readObject();
				AllInstance.put("PaymentMethod", PaymentMethodInstances);
				CouponInstances =  (List<Coupon>) stateLoad.readObject();
				AllInstance.put("Coupon", CouponInstances);
				GeoPointInstances =  (List<GeoPoint>) stateLoad.readObject();
				AllInstance.put("GeoPoint", GeoPointInstances);
				WeChatPaymentInstances =  (List<WeChatPayment>) stateLoad.readObject();
				AllInstance.put("WeChatPayment", WeChatPaymentInstances);
				AlipayUserIdInstances =  (List<AlipayUserId>) stateLoad.readObject();
				AllInstance.put("AlipayUserId", AlipayUserIdInstances);
				
			} catch (ClassNotFoundException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
		
	/* create object */  
	public static Object createObject(String Classifer) {
		try
		{
			Class c = Class.forName("entities.EntityManager");
			Method createObjectMethod = c.getDeclaredMethod("create" + Classifer + "Object");
			return createObjectMethod.invoke(c);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return null;
		}
	}
	
	/* add object */  
	public static Object addObject(String Classifer, Object ob) {
		try
		{
			Class c = Class.forName("entities.EntityManager");
			Method addObjectMethod = c.getDeclaredMethod("add" + Classifer + "Object", Class.forName("entities." + Classifer));
			return  (boolean) addObjectMethod.invoke(c, ob);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return null;
		}
	}	
	
	/* add objects */  
	public static Object addObjects(String Classifer, List obs) {
		try
		{
			Class c = Class.forName("entities.EntityManager");
			Method addObjectsMethod = c.getDeclaredMethod("add" + Classifer + "Objects", Class.forName("java.util.List"));
			return  (boolean) addObjectsMethod.invoke(c, obs);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return null;
		}
	}
	
	/* Release object */
	public static boolean deleteObject(String Classifer, Object ob) {
		try
		{
			Class c = Class.forName("entities.EntityManager");
			Method deleteObjectMethod = c.getDeclaredMethod("delete" + Classifer + "Object", Class.forName("entities." + Classifer));
			return  (boolean) deleteObjectMethod.invoke(c, ob);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return false;
		}
	}
	
	/* Release objects */
	public static boolean deleteObjects(String Classifer, List obs) {
		try
		{
			Class c = Class.forName("entities.EntityManager");
			Method deleteObjectMethod = c.getDeclaredMethod("delete" + Classifer + "Objects", Class.forName("java.util.List"));
			return  (boolean) deleteObjectMethod.invoke(c, obs);
		}
		catch (Exception e)
		{
			e.printStackTrace();
			return false;
		}
	}		 	
	
	 /* Get all objects belongs to same class */
	public static List getAllInstancesOf(String ClassName) {
			 return AllInstance.get(ClassName);
	}	

   /* Sub-create object */
	public static User createUserObject() {
		User o = new User();
		return o;
	}
	
	public static boolean addUserObject(User o) {
		return UserInstances.add(o);
	}
	
	public static boolean addUserObjects(List<User> os) {
		return UserInstances.addAll(os);
	}
	
	public static boolean deleteUserObject(User o) {
		return UserInstances.remove(o);
	}
	
	public static boolean deleteUserObjects(List<User> os) {
		return UserInstances.removeAll(os);
	}
	public static ThirdPartyAccount createThirdPartyAccountObject() {
		ThirdPartyAccount o = new ThirdPartyAccount();
		return o;
	}
	
	public static boolean addThirdPartyAccountObject(ThirdPartyAccount o) {
		return ThirdPartyAccountInstances.add(o);
	}
	
	public static boolean addThirdPartyAccountObjects(List<ThirdPartyAccount> os) {
		return ThirdPartyAccountInstances.addAll(os);
	}
	
	public static boolean deleteThirdPartyAccountObject(ThirdPartyAccount o) {
		return ThirdPartyAccountInstances.remove(o);
	}
	
	public static boolean deleteThirdPartyAccountObjects(List<ThirdPartyAccount> os) {
		return ThirdPartyAccountInstances.removeAll(os);
	}
	public static Deposit createDepositObject() {
		Deposit o = new Deposit();
		return o;
	}
	
	public static boolean addDepositObject(Deposit o) {
		return DepositInstances.add(o);
	}
	
	public static boolean addDepositObjects(List<Deposit> os) {
		return DepositInstances.addAll(os);
	}
	
	public static boolean deleteDepositObject(Deposit o) {
		return DepositInstances.remove(o);
	}
	
	public static boolean deleteDepositObjects(List<Deposit> os) {
		return DepositInstances.removeAll(os);
	}
	public static Bike createBikeObject() {
		Bike o = new Bike();
		return o;
	}
	
	public static boolean addBikeObject(Bike o) {
		return BikeInstances.add(o);
	}
	
	public static boolean addBikeObjects(List<Bike> os) {
		return BikeInstances.addAll(os);
	}
	
	public static boolean deleteBikeObject(Bike o) {
		return BikeInstances.remove(o);
	}
	
	public static boolean deleteBikeObjects(List<Bike> os) {
		return BikeInstances.removeAll(os);
	}
	public static Order createOrderObject() {
		Order o = new Order();
		return o;
	}
	
	public static boolean addOrderObject(Order o) {
		return OrderInstances.add(o);
	}
	
	public static boolean addOrderObjects(List<Order> os) {
		return OrderInstances.addAll(os);
	}
	
	public static boolean deleteOrderObject(Order o) {
		return OrderInstances.remove(o);
	}
	
	public static boolean deleteOrderObjects(List<Order> os) {
		return OrderInstances.removeAll(os);
	}
	public static FaultReport createFaultReportObject() {
		FaultReport o = new FaultReport();
		return o;
	}
	
	public static boolean addFaultReportObject(FaultReport o) {
		return FaultReportInstances.add(o);
	}
	
	public static boolean addFaultReportObjects(List<FaultReport> os) {
		return FaultReportInstances.addAll(os);
	}
	
	public static boolean deleteFaultReportObject(FaultReport o) {
		return FaultReportInstances.remove(o);
	}
	
	public static boolean deleteFaultReportObjects(List<FaultReport> os) {
		return FaultReportInstances.removeAll(os);
	}
	public static PaymentMethod createPaymentMethodObject() {
		PaymentMethod o = new PaymentMethod();
		return o;
	}
	
	public static boolean addPaymentMethodObject(PaymentMethod o) {
		return PaymentMethodInstances.add(o);
	}
	
	public static boolean addPaymentMethodObjects(List<PaymentMethod> os) {
		return PaymentMethodInstances.addAll(os);
	}
	
	public static boolean deletePaymentMethodObject(PaymentMethod o) {
		return PaymentMethodInstances.remove(o);
	}
	
	public static boolean deletePaymentMethodObjects(List<PaymentMethod> os) {
		return PaymentMethodInstances.removeAll(os);
	}
	public static Coupon createCouponObject() {
		Coupon o = new Coupon();
		return o;
	}
	
	public static boolean addCouponObject(Coupon o) {
		return CouponInstances.add(o);
	}
	
	public static boolean addCouponObjects(List<Coupon> os) {
		return CouponInstances.addAll(os);
	}
	
	public static boolean deleteCouponObject(Coupon o) {
		return CouponInstances.remove(o);
	}
	
	public static boolean deleteCouponObjects(List<Coupon> os) {
		return CouponInstances.removeAll(os);
	}
	public static GeoPoint createGeoPointObject() {
		GeoPoint o = new GeoPoint();
		return o;
	}
	
	public static boolean addGeoPointObject(GeoPoint o) {
		return GeoPointInstances.add(o);
	}
	
	public static boolean addGeoPointObjects(List<GeoPoint> os) {
		return GeoPointInstances.addAll(os);
	}
	
	public static boolean deleteGeoPointObject(GeoPoint o) {
		return GeoPointInstances.remove(o);
	}
	
	public static boolean deleteGeoPointObjects(List<GeoPoint> os) {
		return GeoPointInstances.removeAll(os);
	}
	public static WeChatPayment createWeChatPaymentObject() {
		WeChatPayment o = new WeChatPayment();
		return o;
	}
	
	public static boolean addWeChatPaymentObject(WeChatPayment o) {
		return WeChatPaymentInstances.add(o);
	}
	
	public static boolean addWeChatPaymentObjects(List<WeChatPayment> os) {
		return WeChatPaymentInstances.addAll(os);
	}
	
	public static boolean deleteWeChatPaymentObject(WeChatPayment o) {
		return WeChatPaymentInstances.remove(o);
	}
	
	public static boolean deleteWeChatPaymentObjects(List<WeChatPayment> os) {
		return WeChatPaymentInstances.removeAll(os);
	}
	public static AlipayUserId createAlipayUserIdObject() {
		AlipayUserId o = new AlipayUserId();
		return o;
	}
	
	public static boolean addAlipayUserIdObject(AlipayUserId o) {
		return AlipayUserIdInstances.add(o);
	}
	
	public static boolean addAlipayUserIdObjects(List<AlipayUserId> os) {
		return AlipayUserIdInstances.addAll(os);
	}
	
	public static boolean deleteAlipayUserIdObject(AlipayUserId o) {
		return AlipayUserIdInstances.remove(o);
	}
	
	public static boolean deleteAlipayUserIdObjects(List<AlipayUserId> os) {
		return AlipayUserIdInstances.removeAll(os);
	}
  
}

